# -*- coding: utf-8 -*-
import cStringIO as StringIO
from lxml import etree

class HTMLHandle():
    
    __data = ''
    
    def __init__(self, html, target=None):
        self.html = self.__validate_html(html)
        self.target = target
        self.__feedParser(self.html)
        
    def __del__(self):
        if self.target is not None: del self.target
    
    def __validate_html(self, html):
        if html == '': return ''
        tree = etree.parse(StringIO.StringIO(html), etree.HTMLParser(encoding='utf-8'))
        return etree.tostring(tree, pretty_print=True, method='html')
    
    def __feedParser(self, html):
        parser = etree.HTMLParser(encoding='utf-8', target=self.target)
        parser.feed(html)
        parser.feed('')
        self.__data = parser.close()
    
    def getData(self):
        '''Public method to return data'''
        return self.__data


class HTMLTarget():
    
    __data = StringIO.StringIO()
    __silent = 0
    __asilent = 0
    
    
    def __init__(self, target=None, remove_tags=[]):
        self.target = target
        self.remove_tags = remove_tags

    def __del__(self):
        try:
            del self.__data
        except:
            pass
    
    def start(self, tag, attrs):
        self.handle_tag(tag, attrs, True)
    
    def end(self, tag):
        self.handle_tag(tag, {}, False)
    
    def data(self, data):
        if type(data).__name__ == 'unicode': data = data.encode('utf-8')
        if self.__silent == 0 and self.__asilent == 0:
            self.write(data)
    
    def write(self, data):
        self.__data.write(data)
    
    def close(self):
        text = self.__data.getvalue()
        return text
        
    def attrs_to_str(self, attrs):
        if len(attrs) == 0: return ''
        str = ''
        for i, v in attrs.items():
            str += "{0}='{0}' ".format(i, v)
        return str
    
    def handle_tag(self, tag, attrs, is_start):
        if tag in self.remove_tags:
            return ''
        if tag in ['style', 'script', 'meta']:
            if is_start: self.__silent += 1
            elif self.__silent > 0: self.__silent -= 1
            return ''
        if tag == 'a':
            if is_start:
                if self.target.linkDescription is not None:
                    if self.target.linkDescription: self.__asilent += 1
                try:
                    text = self.target.processLink(attrs)
                    if text != '': self.write(text)
                except:
                    self.__asilent += 1
            else: 
                if self.__asilent > 0: self.__asilent -= 1
        elif tag == 'img':
            if is_start:
                try:
                    text = self.target.processImage(attrs)
                    if text != '': self.write(text)
                except: 
                    pass
        elif tag == 'br':
            if is_start: self.write('<br />')
        else:
            if is_start:
                self.write("<%s %s>" % (tag, self.attrs_to_str(attrs)))
            else:
                if tag != '': self.write("</%s>" % tag)
